39e02e
@@ -23,6 +23,7 @@
 package org.jboss.as.patching.metadata;
 
 import java.io.File;
+import java.io.FileFilter;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.Writer;
@@ -178,34 +179,49 @@
public class PatchMerger {
         File modSrcDir = new File(srcPatchDir, srcElementId);
         File modTrgDir = new File(targetPatchDir, targetElementId);
         final ContentType contentType = mod.getItem().getContentType();
-        if(contentType.equals(ContentType.MODULE)) {
-            modSrcDir = new File(modSrcDir, Constants.MODULES);
-            modTrgDir = new File(modTrgDir, Constants.MODULES);
-            for(String name : mod.getItem().getName().split("\\.")) {
-                modSrcDir = new File(modSrcDir, name);
-                modTrgDir = new File(modTrgDir, name);
-            }
-        } else if(contentType.equals(ContentType.BUNDLE)) {
-            modSrcDir = new File(modSrcDir, Constants.BUNDLES);
-            modTrgDir = new File(modTrgDir, Constants.BUNDLES);
-            for(String name : mod.getItem().getName().split("\\.")) {
-                modSrcDir = new File(modSrcDir, name);
-                modTrgDir = new File(modTrgDir, name);
-            }
-        } else if(ContentType.MISC.equals(contentType)) {
+        if(ContentType.MISC.equals(contentType)) {
             modSrcDir = new File(modSrcDir, Constants.MISC);
             modTrgDir = new File(modTrgDir, Constants.MISC);
             for (final String path : ((MiscContentItem)mod.getItem()).getPath()) {
                 modSrcDir = new File(modSrcDir, path);
                 modTrgDir = new File(modTrgDir, path);
             }
+            copyDir(modSrcDir, modTrgDir);
         } else {
-            throw new PatchingException("Unexpected content type " + contentType);
+            if (contentType.equals(ContentType.MODULE)) {
+                modSrcDir = new File(modSrcDir, Constants.MODULES);
+                modTrgDir = new File(modTrgDir, Constants.MODULES);
+                for (String name : mod.getItem().getName().split("\\.")) {
+                    modSrcDir = new File(modSrcDir, name);
+                    modTrgDir = new File(modTrgDir, name);
+                }
+            } else if (contentType.equals(ContentType.BUNDLE)) {
+                modSrcDir = new File(modSrcDir, Constants.BUNDLES);
+                modTrgDir = new File(modTrgDir, Constants.BUNDLES);
+                for (String name : mod.getItem().getName().split("\\.")) {
+                    modSrcDir = new File(modSrcDir, name);
+                    modTrgDir = new File(modTrgDir, name);
+                }
+            } else {
+                throw new PatchingException("Unexpected content type " + contentType);
+            }
+            // copy actual module slots skipping possibly nested modules
+            for (File subDir : modSrcDir.listFiles(new FileFilter() {
+                @Override
+                public boolean accept(File pathname) {
+                    return pathname.isDirectory() && new File(pathname, "module.xml").exists();
+                }
+            })) {
+                copyDir(subDir, new File(modTrgDir, subDir.getName()));
+            }
         }
+    }
+
+    protected static void copyDir(File src, File trg) throws PatchingException {
         try {
-            IoUtils.copyFile(modSrcDir, modTrgDir);
+            IoUtils.copyFile(src, trg);
         } catch (IOException e) {
-            throw new PatchingException("Failed to copy modification content from " + modSrcDir.getAbsolutePath() + " to " + modTrgDir.getAbsolutePath());
+            throw new PatchingException("Failed to copy modification content from " + src.getAbsolutePath() + " to " + trg.getAbsolutePath());
         }
     }
 
